package org.lex.swing.graph;

import java.awt.Color;

import org.lex.swing.graph.ProgressModel.Range;


public class ProgressGraph extends BasicProgressGraph implements ProgressListener {
	private ProgressModel model = null;

	public ProgressGraph(ProgressModel model) {
		this(model, BasicProgressGraph.WIDTH, BasicProgressGraph.HEIGHT);
	}

	public ProgressGraph(ProgressModel model, int width, int height) {
		super(width, height);
		this.setModel(model);
	}

	/**
	 * @return model guarantee not be null
	 */
	public ProgressModel getModel() {
		return model;
	}

	public void setModel(ProgressModel model) {
		if (null == model)
			model = new DefaultProgressModel();
		if (null != this.model)
			this.model.removeGraphListener(this);
		this.model = model;
		this.model.addGraphListener(this);
		this.setSize(this.getWidth(), this.getHeight());
	}

	public void paintModel() {
		// super.reset( this.getWidth(), this.getHeight() );
		if (null == model)
			return;
		long modelMax = model.getMaximum();
		int rowWidth = this.getRowWidth();
		int viewMax = rowWidth * this.getRowCount();
		float k = viewMax / ((float) modelMax);
		Loc from = new Loc();
		Loc to = new Loc();
		for (int i = 0, n = model.getRangeCount(); i < n; i++) {
			Range r = model.getRange(i);
			// convert model range to view range
			from.row = 0;
			from.pos = r.start() * k;
			from.normalize(rowWidth);
			to.row = 0;
			to.pos = r.end() * k;
			to.normalize(rowWidth);
			// draw
			if (from.row == to.row) {
				// only one row
				this.fillForeground(from.row, from.pos, to.pos);
			} else {
				// multi rows
				this.fillForeground(from.row, from.pos, rowWidth);
				while (++from.row < to.row)
					this.fillForeground(from.row, 0, rowWidth);
				this.fillForeground(to.row, 0, to.pos);
			}
		}
	}

	private static class Loc {
		int row = 0;
		float pos = 0;

		void normalize(int viewRowLength) {
			while (pos >= viewRowLength) {
				pos -= viewRowLength;
				row++;
			}
		}

		public String toString() {
			return "[row=" + row + ",pos=" + pos + "]";
		}
	}

	/***************************************************************************
	 * ���е�setters��������Ҫ�ڸı����ú����»�ͼ
	 **************************************************************************/
	/***************************************************************************
	 * Size Setters
	 **************************************************************************/
	public void setHeight(int height) {
		if (height != this.getHeight())
			this.setSize(this.getWidth(), height);
	}

	public void setWidth(int width) {
		if (width != this.getWidth())
			this.setSize(width, this.getHeight());
	}

	public void setRowHeight(int height) {
		if (height != this.getRowHeight())
			;
	}

	public void setRowGap(int gap) {
	}

	public void set(int width, int height, int rowHeight, int gap) {
	}

	@Override
	protected void setSize(int width, int height) {
		super.setSize(width, height);
		this.paintModel();
	}

	/***************************************************************************
	 * Color Setters
	 **************************************************************************/
	public void setBorderColor(Color borderColor) {
		this.borderColor = borderColor;
	}

	@Override
	public void rangesAdded(ProgressEvent e) {
	}

	@Override
	public void rangesRemoved(ProgressEvent e) {
	}

	@Override
	public void boundsChanged(ProgressEvent e) {
		this.paintModel();
	}
}
